package com.imooc.course.server.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.imooc.course.server.dao.CourseDao;
import com.imooc.course.server.dao.my.MyCourseDao;
import com.imooc.course.server.dto.*;
import com.imooc.course.server.entity.Course;
import com.imooc.course.server.entity.CourseCategory;
import com.imooc.course.server.entity.CourseContent;
import com.imooc.course.server.entity.CourseExample;
import com.imooc.course.server.enums.CourseStatusEnum;
import com.imooc.course.server.service.*;
import com.imooc.course.server.utils.CopyUtil;
import com.imooc.course.server.utils.UuidUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

@Service("courseService")
public class CourseServiceImpl implements CourseService {

    private static final Logger log = LoggerFactory.getLogger(CourseServiceImpl.class);

    @Resource(name = "courseDao")
    private CourseDao courseDao;

    @Resource(name = "myCourseDao")
    private MyCourseDao myCourseDao;

    @Resource(name = "courseCategoryService")
    private CourseCategoryService courseCategoryService;

    @Resource(name = "courseContentService")
    private CourseContentService courseContentService;

    @Resource(name = "teacherService")
    private TeacherService teacherService;

    @Resource(name = "chapterService")
    private ChapterService chapterService;

    @Resource(name = "sectionService")
    private SectionService sectionService;

    /**
     * 列表查询
     * @param pageDto
     */
    @Override
    public void getList(CoursePageDto pageDto) {

        CourseExample courseExample = new CourseExample();
        courseExample.setOrderByClause("sort asc");
        CourseExample.Criteria criteria = courseExample.createCriteria();

        List<CourseDto> courseDtoList = this.coursesByConditions(pageDto, courseExample, criteria);

        pageDto.setList(courseDtoList);
    }

    /**
     * 查找该课程下的文本内容
     * @param id
     * @return
     */
    @Override
    public CourseContentDto findById(String id) {
        return courseContentService.getByCourseId(id);
    }

    /**
     * 保存，id有值为更新，id无值为新增
     * @param courseDto
     */
    @Transactional
    @Override
    public void save(CourseDto courseDto) {
        Course course = CopyUtil.copy(courseDto, Course.class);
        String id = courseDto.getId() != null ? courseDto.getId().trim() : courseDto.getId();
        if (StringUtils.isEmpty(id)) {
            this.addCourse(course);
        }else{
            this.updateCourse(course);
        }
        courseDto.setId(course.getId());
        this.saveCourseCategory(courseDto);
    }

    private void addCourse(Course course) {
        course.setId(UuidUtil.getShortUuid());
        courseDao.insertSelective(course);
    }

    private void updateCourse(Course course) {
        courseDao.updateByPrimaryKeySelective(course);
    }

    /**
     * 批量保存分类管理记录
     * @param courseDto
     */
    public void saveCourseCategory(CourseDto courseDto) {
        //数据转换
        List<CourseCategoryDto> courseCategoryDtoList = courseDto.getCategoryDtoList().stream()
                .map(categoryDto -> {
                    CourseCategoryDto ccd = new CourseCategoryDto();
                    ccd.setId(UuidUtil.getShortUuid());
                    ccd.setCourseId(courseDto.getId());
                    ccd.setCategoryId(categoryDto.getId());
                    return ccd;
                }).collect(Collectors.toList());
        //删除原来的course课程关联的分类记录。
        courseCategoryService.removeByCourseId(courseDto.getId());
        //调用courseCategoryServiceImpl的批量保存方法。
        courseCategoryService.addBatch(courseCategoryDtoList);
    }

    /**
     * 删除
     * @param id
     */
    @Override
    public void delete(String id) {
        courseDao.deleteByPrimaryKey(id);
    }

    /**
     * 更新课程视频时长
     * @param courseId
     */
    public void updateTime(String courseId) {
        myCourseDao.updateTime(courseId);
    }

    @Override
    public List<CourseCategory> getCategoryList(String courseId) {
        return courseCategoryService.getListByCourseId(courseId);
    }

    /**
     * 保存或更新该课程下的文本内容
     * @param courseContentDto
     */
    @Override
    public void saveContent(CourseContentDto courseContentDto) {
        CourseContent courseContent = CopyUtil.copy(courseContentDto, CourseContent.class);
        int affectRow = this.modifyCourseContent(courseContent);
        if (affectRow <= 0) {
            this.addCourseContent(courseContent);
        }
    }

    @Override
    public int modifyCourseContent(CourseContent courseContent) {
        return courseContentService.modifyCourseContent(courseContent);
    }

    @Override
    public int addCourseContent(CourseContent courseContent) {
        return courseContentService.addCourseContent(courseContent);
    }

    @Transactional
    @Override
    public void setTheSort(SortDto sortDto) {
        try {
            //先修改sort
            CourseExample example = new CourseExample();
            example.createCriteria().andIdEqualTo(sortDto.getId());
            Course course = new Course();
            course.setSort(sortDto.getNewSort());
            courseDao.updateByExampleSelective(course, example);
            //如果old>new，则Backward向后移动然后排序
            if (sortDto.getOldSort() > sortDto.getNewSort()) {
                myCourseDao.sortMoveBackward(sortDto);
            }
            //如果old<new，则Forward向前移动然后排序
            if (sortDto.getOldSort() < sortDto.getNewSort()) {
                myCourseDao.sortMoveForward(sortDto);
            }
        } catch (Exception e) {
            throw new RuntimeException("自定义排序出错");
        }
    }

    @Override
    public void getNewlyReleasedCourseList(CoursePageDto pageDto) {

        CourseExample courseExample = new CourseExample();
        courseExample.setOrderByClause("created_at desc");
        CourseExample.Criteria criteria = courseExample.createCriteria();

        List<CourseDto> courseDtoList = this.coursesByConditions(pageDto, courseExample, criteria);

        pageDto.setList(courseDtoList);
    }


    /**
     * 查询报名数最多的课程
     * @param pageDto
     */
    @Override
    public void getHotCourses(CoursePageDto pageDto) {

        CourseExample example = new CourseExample();
        example.setOrderByClause("enroll desc");
        CourseExample.Criteria criteria = example.createCriteria();

        List<CourseDto> courseDtos = this.coursesByConditions(pageDto, example, criteria);

        pageDto.setList(courseDtos);
    }

    private List<CourseDto> coursesByConditions(CoursePageDto pageDto, CourseExample example, CourseExample.Criteria criteria) {

        PageHelper.startPage(pageDto.getPage(), pageDto.getSize());

        if (!StringUtils.isEmpty(pageDto.getStatus())) {
            criteria.andStatusEqualTo(pageDto.getStatus());
        }

        List<Course> courseList = courseDao.selectByExample(example);

        PageInfo<Course> coursePageInfo = new PageInfo<>(courseList);
        pageDto.setTotal(coursePageInfo.getTotal());

        List<CourseDto> courseDtoList = CopyUtil.copyList(courseList, CourseDto.class);
        return courseDtoList;
    }

    /**
     * 通过分类搜索精选课程
     * @param pageDto
     */
    @Override
    public void searchCoursesByCategoryId(CoursePageDto pageDto) {
        List<Course> courseList = myCourseDao.selectByCategoryId(pageDto);
        pageDto.setList(courseList);
    }

    @Override
    public CourseDto getCourseDetailByCourseId(String courseId) {
        //先获取课程
        Course course = courseDao.selectByPrimaryKey(courseId);
        if (!course.getStatus().equals(CourseStatusEnum.PUBLISH.getCode())) {
            //如果课程为未发布状态，或其他状态，不再查询。
            return null;
        }
        //转换为dto
        CourseDto courseDto = CopyUtil.copy(course, CourseDto.class);

        //获取该课程的分类
        List<CategoryDto> categoryDtoList = courseCategoryService.getCategorysByCourseId(courseId);
        courseDto.setCategoryDtoList(categoryDtoList);

        //获取该课程的讲师
        TeacherDto teacherDto = teacherService.getById(courseDto.getTeacherId());
        courseDto.setTeacherDto(teacherDto);

        //获取该课程的大章列表
        List<ChapterDto> chapterDtoList = chapterService.getListByCourseId(courseId);
        courseDto.setChapterDtoList(chapterDtoList);

        //获取该课程所有的小节列表
        List<SectionDto> sectionDtoList = sectionService.getListByCourseId(courseId);
        courseDto.setSectionDtoList(sectionDtoList);

        //获取该课程的内容描述
        CourseContentDto courseContentDto = courseContentService.getByCourseId(courseId);
        courseDto.setCourseContentDto(courseContentDto);

        return courseDto;
    }

}
